#ifndef ATTRIBUTE_HPP
#define ATTRIBUTE_HPP

//! Manages a single attribute. You can add an attribute bonus that restores
//! after a certain number of calls to Tick.

class Attribute
{
public:
    //! Constructor.
    Attribute(int cur=0, int max=0);
    virtual ~Attribute() { }
    
    //! \return The current attribute value.
    virtual int GetCurrent() const { return m_cur; }
    //! Sets the current attribute value.
    virtual void SetCurrent(int to) { m_cur = to; }
    //! Modifies the current attribute value by some delta.
    virtual void ModCurrent(int delta) { m_cur += delta; }
    
    //! \return The maximum attribute value by some delta.
    virtual int GetMaximum() const { return m_max; }
    //! Sets the maximum attribute value.
    virtual void SetMaximum(int to) { m_max = to; }
    //! Modifies the maximum attribute value by some delta.
    virtual void ModMaximum(int delta) { m_max += delta; }
    
    //! \return The bonus to the current attribute value.
    virtual int GetBonus() const { return m_bonus; }
    //! Sets the bonus to the current attribute value.
    virtual void SetBonus(int to) { m_bonus = to; }
    //! Modifies the bonus to the current attribute value by some delta.
    virtual void ModBonus(int delta) { m_bonus += delta; }
    
    //! \return The tick count.
    virtual int GetTicks() const { return m_ticks; }
    //! Sets the tick count.
    virtual void SetTicks(int to) { m_ticks = to; }
    //! Modifies the tick count by some delta.
    virtual void ModTicks(int delta) { m_ticks += delta; }
    
    //! One tick. If the tick counter hits 0 (or is at 0), bonus is reset back
    //! to 0.
    virtual void Tick() { if (m_ticks-- <= 0) m_bonus = 0; }
protected:
    int m_cur, m_max;
    int m_bonus;
    int m_ticks;
};

//! A class that manages the body attributes along with the type of body.

class BodyAttributes
{
public:
    //! The type of body. One of these is passed to the constructor.
    enum
    {
        STRONG, BULKY, BRUTE, AGILE, WITHY, STEADFAST, TOUGH, JUGGERNAUT,
        BRUISER, SCRAWNY, WEAK, CRIPPLED, MAX_TYPES
    };
    
    //! Constructor.
    BodyAttributes(int type, int start);
    virtual ~BodyAttributes() { }
    
    //! \return A reference to the brawn Attribute.
    virtual Attribute &GetBrawn() { return m_brawn; }
    //! \return The multiplier for the brawn Attribute.
    //! \note The attribute's current and maximum values are the only values
    //!       effected by the multiplier.
    virtual double GetBrawnMultiplier() const { return m_brawnMult; }
    //! \return A reference to the deft Attribute.
    virtual Attribute &GetDeft() { return m_deft; }
    //! \return The multiplier for the deft Attribute.
    //! \note The attribute's current and maximum values are the only values
    //!       effected by the multiplier.
    virtual double GetDeftMultiplier() const { return m_deftMult; }
    //! \return A reference to the grit Attribute.
    virtual Attribute &GetGrit() { return m_grit; }
    //! \return The multiplier for the grit Attribute.
    //! \note The attribute's current and maximum values are the only values
    //!       effected by the multiplier.
    virtual double GetGritMultiplier() const { return m_gritMult; }
    
    //! \return The type.
    virtual int GetType() const { return m_type; }
    
protected:
    int m_type;
    Attribute m_brawn;
    Attribute m_deft;
    Attribute m_grit;
    double m_brawnMult;
    double m_deftMult;
    double m_gritMult;
};

//! A class that manages the mind attributes along with the type of mind.

class MindAttributes
{
public:
    //! The type of body. One of these is passed to the constructor.
    enum
    {
        WILLFUL, RESOURCEFUL, CALM, WITTY, SMART, BRILLIANT, POWERFUL,
        INSANE, CLAIRVOYANT, DUMB, POMPOUS, POWERLESS, MAX_TYPES
    };
    
    //! Constructor.
    MindAttributes(int type, int start);
    virtual ~MindAttributes() { }
    
    //! \return A reference to the power Attribute.
    virtual Attribute &GetPower() { return m_power; }
    //! \return The multiplier for the power Attribute.
    //! \note The attribute's current and maximum values are the only values
    //!       effected by the multiplier.
    virtual double GetPowerMultiplier() const { return m_powerMult; }
    //! \return A reference to the wit Attribute.
    virtual Attribute &GetWit() { return m_wit; }
    //! \return The multiplier for the wit Attribute.
    //! \note The attribute's current and maximum values are the only values
    //!       effected by the multiplier.
    virtual double GetWitMultiplier() const { return m_witMult; }
    //! \return A reference to the will Attribute.
    virtual Attribute &GetWill() { return m_will; }
    //! \return The multiplier for the will Attribute.
    //! \note The attribute's current and maximum values are the only values
    //!       effected by the multiplier.
    virtual double GetWillMultiplier() const { return m_willMult; }
    
    //! \return The type.
    virtual int GetType() const { return m_type; }
    
protected:
    int m_type;
    Attribute m_power;
    Attribute m_wit;
    Attribute m_will;
    double m_powerMult;
    double m_witMult;
    double m_willMult;
};

#endif
